<template>
  <div class="users">
    <!--Breadcrumb面包屑组件-->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>用户管理</el-breadcrumb-item>
      <el-breadcrumb-item>管理列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!--Card卡片组件-->
    <el-card class="box-card">
      <!--搜索与添加区-->
      <!--input输入框组件-->

      <!--Layout布局组件-->
      <!--row栅格组件-->
      <!--gutter是栅格之间的间隔，默认单位是像素-->
      <!--span是该栅格的宽度，一行栅格最大宽度总和24-->
      <el-row :gutter="20">
        <el-col :span="10">
          <!--clearable开启内容清除按钮-->
          <!--点击input组件中的clearable清除按钮时触发会触发clear事件-->
          <el-input
            placeholder="请输入要查找的用户姓名"
            v-model="queryInfo.query"
            clearable
            @clear="getUserList"
          >
            <el-button slot="append" icon="el-icon-search" @click="getUserList">
            </el-button> </el-input
        ></el-col>
        <el-col :span="1.5">
          <el-button type="primary" @click="addUserDialog = true"
            >添 加</el-button
          >
          <!--使用Dialog组件实现添加用户对话框布局-->
          <!--:visible.sync控制对话框显示或关闭，接收一个布尔值，true时显示false关闭-->
          <!--@close对话框关闭事件，在关闭对话框时会触发这个事件回调函数-->
        </el-col>
        <el-col :span="1.5"
          ><el-button @click="getUserList">刷 新</el-button></el-col
        >
      </el-row>

      <!--table表格组件  用户列表区-->
      <!--border开启表格边框-->
      <!--stripe开启斑马纹-->
      <el-table :data="userList" border stripe style="width: 100%">
        <!--type="index"该表格渲染数据的index值-->
        <el-table-column
          class="tableTitle"
          type="index"
          label="#"
          width="50"
        ></el-table-column>
        <el-table-column
          class="tableTitle"
          prop="username"
          label="姓名"
          width="180"
        >
        </el-table-column>
        <el-table-column
          class="tableTitle"
          prop="email"
          label="邮箱"
          width="180"
        >
        </el-table-column>
        <el-table-column class="tableTitle" prop="mobile" label="电话">
        </el-table-column>
        <el-table-column class="tableTitle" prop="role_name" label="角色">
        </el-table-column>
        <el-table-column class="tableTitle" label="状态">
          <!--slot-scope作用域插槽-->
          <!--scope.row是该行的数据对象-->
          <template slot-scope="scope">
            <!--switch开关组件-->
            <!--@chang监听switch组件v-model绑定的数据，变化时调用回调函数-->
            <el-switch
              v-model="scope.row.mg_state"
              @change="userStatusChanged(scope.row)"
              active-color="#13ce66"
              inactive-color="#ff4949"
            >
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column class="tableTitle" label="操作" width="180">
          <template slot-scope="scope">
            <!--修改用户信息-->
            <el-button
              type="primary"
              icon="el-icon-edit"
              @click="getUpDateUserForm(scope.row.id)"
              size="mini"
            ></el-button>
            <!--删除用户-->
            <el-button
              :disabled="scope.row.username === 'admin'"
              type="danger"
              icon="el-icon-delete"
              size="mini"
              @click="getDeleUserDialog(scope.row.id)"
            ></el-button>
            <!--          Tooltip提示文字框组件-->
            <!--enterable鼠标是否能移入提示框中,false不能-->
            <!--open-delay延迟多少毫秒再出现提示框-->
            <el-tooltip
              :open-delay="700"
              :enterable="false"
              class="item"
              effect="dark"
              content="分配角色"
              placement="top"
            >
              <el-button
                @click="getSetRolesDialog(scope.row)"
                type="warning"
                icon="el-icon-setting"
                size="mini"
                :disabled="scope.row.username === 'admin'"
              ></el-button>
            </el-tooltip>
          </template>
        </el-table-column>
      </el-table>
      <!--pagination分页组件-->
      <!--@size-change改变每页显示数据条数时会触发此事件-->
      <!--current-change是翻页事件-->
      <!--current-page绑定当前页码-->
      <!--page-sizes传入一个数组，数组中的每一项就是可选的每页展示数据的数量-->
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="queryInfo.pagenum"
        :page-sizes="[2, 15, 20, 25]"
        :page-size="queryInfo.pagesize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
      >
      </el-pagination>
    </el-card>
    <!--    添加用户对话框-->
    <el-dialog
      title="添加用户"
      :visible.sync="addUserDialog"
      width="30%"
      @close="restAddUserForm"
    >
      <!--内容主体区-->
      <el-form
        :model="addUserForm"
        :rules="addUsersRules"
        ref="addUserFormRef"
        label-width="90px"
        class="demo-ruleForm"
      >
        <!--防止浏览器自动获取用户名和密码进行填充-->
        <input
          hidden
          type="text"
          name="fakeusernameremembered"
          autocomplete="new-password"
        />
        <input
          hidden
          type="password"
          name="fakepasswordremembered"
          autocomplete="new-password"
        />
        <el-form-item label="用户名" prop="username">
          <el-input v-model="addUserForm.username"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input
            type="password"
            v-model="addUserForm.password"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="确认密码" type="password" prop="checkPass">
          <el-input
            type="password"
            v-model="addUserForm.checkPass"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="addUserForm.email"></el-input>
        </el-form-item>
        <el-form-item label="联系电话" prop="mobile">
          <el-input v-model="addUserForm.mobile"></el-input>
        </el-form-item>
      </el-form>
      <!--底部区-->
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="addUser">添 加</el-button>
        <el-button @click="addUserDialog = false">取 消</el-button>
      </span>
    </el-dialog>
    <!--修改用户的对话框-->
    <el-dialog
      title="修改用户"
      :visible.sync="upDateUserDialog"
      width="30%"
      @close="restUpDateUserForm"
    >
      <el-form
        :model="upDateUserForm"
        :rules="upDateUsersRules"
        ref="upDateUserFormRef"
        label-width="70px"
        class="demo-ruleForm"
      >
        <el-form-item label="用户名">
          <el-input disabled v-model="upDateUserForm.username"></el-input>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="upDateUserForm.email"></el-input>
        </el-form-item>
        <el-form-item label="联系电话" prop="mobile">
          <el-input v-model="upDateUserForm.mobile"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer"
        ><el-button type="primary" @click="upDateUser">修 改</el-button
        ><el-button @click="upDateUserDialog = false">取 消</el-button></span
      >
    </el-dialog>
    <el-dialog
      @close="colseRolesDialog"
      :visible.sync="setRolesDialog"
      title="分配角色"
      width="30%"
    >
      <div class="setRoles">
        <p>当前用户：{{ setUser.username }}</p>
        <p>当前角色：{{ setUser.role_name }}</p>
        <p>
          <!--v-model绑定将选中的选项的值传到哪个变量中-->
          分配新角色：<el-select
            v-model="selectedRoleId"
            placeholder="请选择新角色"
          >
            <el-option
              :label="item.roleName"
              :value="item.id"
              v-for="item in rolesList"
              :key="item.id"
            ></el-option>
          </el-select>
        </p>
      </div>

      <span slot="footer">
        <el-button type="primary" @click="setRoles">确 定</el-button>
        <el-button @click="setRolesDialog = false">取 消</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
// import {}
export default {
  name: "users",
  data() {
    //  创建检查规则函数
    var validatePass = (rule, value, callback) => {
      //  rule是检查字段对象
      //  二次输入密码验证规则
      if (value === "") {
        //  value是v-model绑定的数据值
        callback(new Error("请再次输入密码"));
      } else if (value !== this.addUserForm.password) {
        callback(new Error("两次输入密码不一致!"));
      } else {
        callback(); //  通过验证时调用callback
      }
    };
    return {
      //  获取用户列表配置参数
      queryInfo: {
        //  搜索关键字
        query: "",
        //  pagenum当前展示的页码
        pagenum: 1,
        // 当前每页显示多少条数据
        pagesize: 2
      },
      userList: [],
      total: 0, //  总共多少条数据
      addUserDialog: false, // 控制添加用户对话框显示或关闭
      upDateUserDialog: false,
      deleUserDialog: false,
      setRolesDialog: false,
      //  要分配角色的用户当前的角色信息
      setUser: {},
      //  新分配的角色的ID
      selectedRoleId: "",
      //  当前可以分配的角色列表
      rolesList: [],
      //  修改用户表单数据
      upDateUserForm: {},
      //  添加用户表单数据
      addUserForm: {
        username: "",
        password: "",
        checkPass: "",
        email: "",
        mobile: ""
      },
      //  添加用户表单验证规则
      addUsersRules: {
        username: [
          {
            required: true,
            message: "必须填写用户名",
            trigger: "blur"
          },
          {
            min: 3,
            max: 10,
            message: "用户名长度应在3到10个字符",
            trigger: "blur"
          }
        ],
        password: [
          {
            required: true,
            message: "必须填写用户密码",
            trigger: "blur"
          },
          {
            min: 6,
            max: 15,
            message: "密码长度须在6~15个字符",
            trigger: "blur"
          }
        ],
        email: [
          {
            pattern: /^\w{5,12}@(qq|163|126|sina)\.(com|cn)$/, // 邮箱格式正则
            message: "请填写正确的邮箱格式!",
            trigger: "blur"
          }
        ],
        mobile: [
          {
            pattern: /^1\d{10}$/,
            message: "请填写正确的手机号格式!",
            trigger: "blur"
          }
        ],
        checkPass: [
          //  指向检查规则函数
          // 二次输入密码验证检查
          {
            required: true,
            message: "请再次输入密码",
            trigger: "blur"
          },
          {
            validator: validatePass,
            trigger: "blur"
          }
        ]
      },
      upDateUsersRules: {
        email: [
          {
            pattern: /^\w{5,12}@(qq|163|126|sina)\.(com|cn)$/, // 邮箱格式正则
            message: "请填写正确的邮箱格式!",
            trigger: "blur"
          }
        ],
        mobile: [
          {
            pattern: /^1\d{10}$/,
            message: "请填写正确的手机号格式!",
            trigger: "blur"
          }
        ]
      }
    };
  },
  created() {
    this.getUserList();
  },
  methods: {
    async getUserList() {
      //  get请求要使用{params:参数对象}来传递
      const { data: res } = await this.$http.get("users", {
        params: this.queryInfo
      });
      if (res.meta.status !== 200)
        return this.$message.error("用户列表获取失败!");
      this.userList = res.data.users;
      this.total = res.data.total;
      return res.meta.status === 200;
    },
    //  监听pagesize改变的事件
    handleSizeChange(newSize) {
      this.queryInfo.pagesize = newSize;
      this.getUserList(); //  改变每页显示的数据后重新请求数据
    },
    handleCurrentChange(current) {
      // 接收的是翻页后的页码
      this.queryInfo.pagenum = current;
      this.getUserList();
    },
    async userStatusChanged(userInfo) {
      //  switch组件v-model双向绑定的变量发生变化时触发该回调函数
      //  改变数据后需要调用API来保存到数据库中 文档1.3.3
      const { data: res } = await this.$http.put(
        `users/${userInfo.id}/state/${userInfo.mg_state}`
      );
      if (res.meta.status !== 200) {
        userInfo.mg_state = !userInfo.mg_state; //  如果修改失败，则将前端中绑定的这个数据再恢复
        return this.$message.error("用户状态设置失败！");
      }
      this.$message.success("用户状态设置成功！");
    },
    restAddUserForm() {
      this.$refs.addUserFormRef.resetFields();
    },
    //  添加用户
    addUser() {
      this.$refs.addUserFormRef.validate(async (valid) => {
        if (!valid) return;
        const { data: res } = await this.$http.post("users", this.addUserForm);
        if (res.meta.status !== 201)
          return this.$message.error("添加用户失败，请重试！");
        this.$message.success("添加成功!");
        this.getUserList(); // 添加完成之后重新获取用户列表
        this.addUserDialog = false;
      });
    },
    async getUpDateUserForm(id) {
      const { data: res } = await this.$http.get(`users/${id}`);
      if (res.meta.status !== 200)
        return this.$message.error("获取该用户信息失败，请重试!");
      this.upDateUserForm = res.data;
      this.upDateUserDialog = true;
    },
    upDateUser() {
      this.$refs.upDateUserFormRef.validate(async (valid) => {
        if (!valid)
          return this.$message.error("表单预验证失败，请检查信息格式!");
        const { data: res } = await this.$http.put(
          `users/${this.upDateUserForm.id}`,
          {
            email: this.upDateUserForm.email,
            mobile: this.upDateUserForm.mobile
          }
        );
        if (res.meta.status !== 200)
          return this.$message.error("修改提交失败，请重试!");
        this.getUserList();
        this.upDateUserDialog = false;
        this.$message.success("修改成功!");
      });
    },
    restUpDateUserForm() {
      this.$refs.upDateUserFormRef.resetFields();
    },
    getDeleUserDialog(id) {
      //  confirm需要在element.js中引入MessageBox再将MessageBox.confirm挂载到Vue.Prototype上
      //  后续操作，可以判断$confirm函数的（点击按钮之后）返回值来进行。点击"确认"按钮返回confirm，点击"取消"按钮返回cancel,点击取消时，相当于primise的一个错误，可以被.catch捕获。也可以使用then方法进行。
      this.$confirm("此操作将永久删除该用户, 是否继续?", "删除用户", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(async () => {
          const { data: res } = await this.$http.delete(`users/${id}`);
          if (res.meta.status !== 200) {
            return this.$message.error("用户删除失败，请重试！");
          }
          this.getUserList();
          this.$message({
            type: "success",
            message: "删除成功!"
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除"
          });
        });
    },
    async getSetRolesDialog(user) {
      this.setUser = user;
      const { data: res } = await this.$http.get("roles");
      if (res.meta.status !== 200)
        return this.$message.error("获取角色列表失败，请重试!");
      this.rolesList = res.data;
      this.setRolesDialog = true;
    },
    //  给用户分配新角色
    async setRoles() {
      if (!this.selectedRoleId)
        return this.$message.error("未选择新分配的角色，请选择后重试!");
      const { data: res } = await this.$http.put(
        `users/${this.setUser.id}/role`,
        { rid: this.selectedRoleId }
      );
      if (res.meta.status !== 200) {
        console.log(res);
        return this.$message.error("分配角色失败，请重试!");
      }
      this.getUserList();
      this.$message.success("分配角色成功!");
      this.setRolesDialog = false;
    },
    colseRolesDialog() {
      this.selectedRoleId = "";
    }
  }
};
</script>

<style scoped lang="less">
//Card卡片组件样式 在css/global.css中
.el-row {
  //.el-col {
  //  height: 40px;
  //  line-height: 40px;
  //}
}
.el-table {
  margin-top: 15px;
}
.el-table_header-wrapper {
  height: 15px;
}
.el-pagination {
  margin-top: 10px;
}
.el-col {
  text-align: center;
}
.setRoles {
  p {
    margin: 10px 0;
  }
}
</style>
